var handle,
  weeks_ch = ["日", "一", "二", "三", "四", "五", "六"],
  dateType = "yyyy|y|mm|m|dd|d|hh|h|ii|i|ss|s",
  sysInfo = wx.getSystemInfoSync(),
  _ = require("../lib/underscore.js"),
  fsm = wx.getFileSystemManager()

handle = {
  /**
   * JS 混合模式
   * @param  {object}   r   混合原对象
   * @param  {object}   s   需要混入对象
   * @return {object}   r   返回混合后对象
   */
  mixin: function(r, s) {
    var p
    for (p in s) {
      r[p] = s[p]
    }
    return r
  },

  /**
   * 时间戳转换为对象 (new Date()) => (timeObject)
   * @param  {Number}   time   传入原时间
   * @return {Object}   object 转换后的时间戳，和时间对象
   */
  timeToDateObj: function(time = new Date().getTime()) {
    var date = new Date()
    date.setTime(time)

    return {
      time: time,
      day: date.getDate(),
      month: date.getMonth() + 1,
      year: date.getFullYear(),
      week: weeks_ch[date.getDay()],
      hours: date.getHours(),
      minutes: date.getMinutes(),
      seconds: date.getSeconds(),
      monthStr: this.digit(date.getMonth() + 1),
      dayStr: this.digit(date.getDate()),
      hoursStr: this.digit(date.getHours()),
      minutesStr: this.digit(date.getMinutes()),
      secondsStr: this.digit(date.getSeconds())
    }
  },

  /**
   * 格式化时间戳
   * @param  {Number}    time           需要转换的时间戳。默认当前时间
   * @param  {String}    format         时间格式 默认 yyyy-mm-dd HH:ii:ss
   * @return {String}    timeStr        格式化后的字符串
   */
  formateTime: function(time = new Date().getTime(), format = "yyyy-mm-dd hh:ii:ss") {
    // 转换时间对象
    var timeObj = this.timeToDateObj(time)
    // 正则
    format = format.toLocaleLowerCase().match(new RegExp(dateType + "|.", "g")) || []
    // 匹配格式
    _.each(format, (v, i) => {
      if (/yyyy|y/.test(v)) {
        //年
        format[i] = this.digit(timeObj.year, v.length)
      } else if (/mm|m/.test(v)) {
        //月
        format[i] = this.digit(timeObj.month, v.length)
      } else if (/dd|d/.test(v)) {
        //日
        format[i] = this.digit(timeObj.day, v.length)
      } else if (/hh|h/.test(v)) {
        //时
        format[i] = this.digit(timeObj.hours, v.length)
      } else if (/ii|i/.test(v)) {
        //分
        format[i] = this.digit(timeObj.minutes, v.length)
      } else if (/ss|s/.test(v)) {
        //秒
        format[i] = this.digit(timeObj.seconds, v.length)
      }
    })
    return format.join("")
  },

  /**
   * 数字前置补零
   * @param  {Number}  num     传入的数字
   * @param  {Number}  length  需要的长度。默认2位
   * @return {Number}  num     转换好的数字
   */
  digit: function(num, length) {
    var str = ""
    num = String(num)
    length = length || 2
    for (var i = num.length; i < length; i++) {
      str += "0"
    }
    return num < Math.pow(10, length) ? str + (num | 0) : num
  },

  /**
   * 打开小程序设置，重新设置授权
   * @param {Object} modal 授权弹窗的title和内容
   * @param {function} callback 回调函数，非必填
   */
  setting: function(modal = {}, callback) {
    wx.showModal({
      title: modal.title || "请授权",
      content: modal.content || "使用该功能需要您授权允许对应的权限",
      showCancel: true,
      cancelText: "取消",
      cancelColor: "#000000",
      confirmText: "去设置",
      confirmColor: "#3CC51F",
      success: result => {
        if (result.confirm) {
          wx.openSetting({
            success(setting) {
              callback && callback(setting)
            }
          })
        }
      }
    })
  },

  /**
   * 公共弹窗
   * @param {String}  msg  弹窗消息 必填
   * @param {String}  icon  弹窗icon。[ none | success | loading ]
   * @param {number}  time  弹窗持续时间
   * @param {Boolean}  mask  是否禁止穿透
   */
  toast: function(msg = "", icon = "none", time = 2000, mask = false) {
    return new Promise(resolve => {
      // 处理icon问题。超出7个字后隐藏
      msg.length > 7 && icon != "none" ? (icon = "none") : ""
      // if(icon != 'none')
      wx.showToast({
        title: msg,
        icon: icon,
        duration: time,
        mask: mask,
        complete: () => setTimeout(() => resolve(), time)
      })
    })
  },
  /**
   * rpx参数转为对应真机的px像素
   * @param {Number} rpx 传入rpx
   * @return {Number} 返回对应真机上的px像素
   */
  toPx: function(rpx) {
    return rpx / (750 / sysInfo.windowWidth)
  },
  /**
   * px参数转为对应真机rpx的像素
   * @param {Number} px 传入 px
   * @return {Number} 返回对应真机上的rpx像素
   */
  toRpx: function(px) {
    return (px * 750) / sysInfo.windowWidth
  },
  /**
   * 正则验证手机号
   * @param {Number} mobile 需要验证的手机号
   * @return {Boolean} 验证结果
   */
  checkMobile: function(mobile) {
    return /^1\d{10}$/.test(mobile)
  },

  /**
   * 预览图片
   * @param {String}  imgUlr  预览图片的路径  （必传）
   * @param {Array}   imgList 预览图片的数组，默认是一张图片（非必须传）
   */
  previewImg: function(imgUlr, imgList = [imgUlr]) {
    wx.previewImage({
      current: imgUlr, // 当前显示图片的http链接
      urls: imgList // 需要预览的图片http链接列表
    })
  },

  /**
   * 获取图片的本地路径
   * @param {String} url 图片的路径
   * @param {String|Array} key 需要的字段
   */
  getImgInfo: function(url, key) {
    if (!url) return Promise.reject({ msg: "图片有误" })
    return new Promise((resolve, reject) => {
      wx.getImageInfo({
        src: url,
        success: result => {
          if (key) resolve(_.pick(result, key))
          else resolve(result)
        },
        fail: () => {
          reject({ msg: "获取失败" })
        }
      })
    })
  },
  /**
   * 下载canvas图片
   * @param {String} url 图片的路径
   * @param {String|Array} key 需要的字段
   */
  downCanvas: function(canvasId) {
    if (!canvasId) return Promise.reject({ code: 0, msg: "canvasID有误" })
    return new Promise((resolve, reject) => {
      // canvas转图片
      wx.canvasToTempFilePath({
        canvasId: canvasId,
        success: res => {
          // 保存到相册
          wx.saveImageToPhotosAlbum({
            filePath: res.tempFilePath,
            success: () => {
              resolve({ code: 1, msg: "保存成功" })
            },
            fail: savsFail => {
              switch (savsFail.errMsg) {
                case "saveImageToPhotosAlbum:fail cancel":
                  reject({ code: 0, msg: "取消保存" })
                  break
                case "saveImageToPhotosAlbum:fail auth deny":
                case "saveImageToPhotosAlbum:fail authorize no response":
                  this.setting({ title: "保存失败", content: "请打开设置页允许保存图片到相册中" })
                  reject({ code: 0, msg: "保存失败" })
                  break
                default:
                  this.setting({ title: "保存失败", content: "请打开设置页允许保存图片到相册中" })
                  reject({ code: 0, msg: "保存失败" })
                  break
              }
            }
          })
        },
        fail: res => {
          reject({ code: -1, msg: res.errMsg }) // canvas生成失败
        }
      })
    })
  },

  /**
   * 倒计时
   * @param {Number} endTime 结束时间
   */
  getTimeCounter: function(endTime) {
    // var pageData = caller.data.pageData
    var curTime = new Date().getTime()
    var leftTime = endTime - curTime
    var leftTimeStr = ""
    var timeObj = {}
    if (leftTime > 0) {
      leftTimeStr = "剩余 "
      timeObj = {
        day: this.digit(Math.floor(leftTime / 1000 / 60 / 60 / 24)),
        hoursStr: (Math.floor((leftTime / 1000 / 60 / 60) % 24) / 100).toFixed(2).split(".")[1],
        minutesStr: (Math.floor((leftTime / 1000 / 60) % 60) / 100).toFixed(2).split(".")[1],
        secondsStr: (Math.floor((leftTime / 1000) % 60) / 100).toFixed(2).split(".")[1],
        end: false
      }
      if (timeObj.day / 1 > 0) {
        leftTimeStr = leftTimeStr + timeObj.day + "天"
      }
      timeObj.timeStr = leftTimeStr + timeObj.hoursStr + ":" + timeObj.minutesStr + ":" + timeObj.secondsStr
    } else {
      timeObj = {
        day: 0,
        hoursStr: 0,
        minutesStr: 0,
        secondsStr: 0,
        end: true,
        timeStr: "已结束"
      }
    }

    return timeObj
  },

  /**
   * base64图片转本地图片
   */
  base64ToFile: function(base64data) {
    return new Promise((resolve, reject) => {
      const [, format, bodyData] = /data:image\/(\w+);base64,(.*)/.exec(base64data) || []
      if (!format) {
        reject(new Error("ERROR_BASE64SRC_PARSE"))
      }
      const filePath = `${wx.env.USER_DATA_PATH}/${new Date().getTime()}.${format}`
      const buffer = wx.base64ToArrayBuffer(bodyData)
      fsm.writeFile({
        filePath,
        data: buffer,
        encoding: "binary",
        success() {
          resolve(filePath)
        },
        fail() {
          reject(new Error("ERROR_BASE64SRC_WRITE"))
        }
      })
    })
  },
  /**
   * 获取小程序二维码参数
   */
  getScene(scene = "") {
    if (scene == "") return {}
    let res = {}
    let params = decodeURIComponent(scene).split("&")
    params.forEach(item => {
      let pram = item.split("=")
      res[pram[0]] = pram[1]
    })
    return res
  }
}

module.exports = handle
